package com.example.demo.http;

import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

/**
 * http请求重试策略
 * @author zyc
 */
public class HttpRequestRetryHandlerManager {

    /**
     * 尝试两次后如果还不行就不再进行连接
     */
    private static final int TRY_COUNT = 2;

    /**
     * 请求重试处理
     */
    public static final HttpRequestRetryHandler REQUEST_RETRY_HANDLER = (exception, executionCount, httpContext) -> {
        if (executionCount > TRY_COUNT) {// 重试次数
            return false;
        }
        if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
            return false;
        }
        if (exception instanceof UnknownHostException) {// 目标服务器不可达
            return false;
        }
        if (exception instanceof ConnectTimeoutException) {// 链接超时
            return false;
        }
        if (exception instanceof SSLException) {// ssl握手异常
            return false;
        }

        if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接，那么就重试
            return true;
        }
        if (exception instanceof InterruptedIOException) {// 被中断
            return true;
        }
        HttpClientContext clientContext = HttpClientContext.adapt(httpContext);
        HttpRequest request = clientContext.getRequest();
        // 如果请求是幂等的，就再次尝试
        if (!(request instanceof HttpEntityEnclosingRequest)) {
            return true;
        }
        return false;
    };

}
